﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using One.Models;
using OneSpider.Extensions;
using OneSpider.Helper;
using OneSpider.Models.ResultModel;
using OneSpider.Models.ResultModelV2;

namespace OneSpider.API
{
    public class ApiServiceV2 : HttpBaseService, IApiService
    {
        public static string Token { get; set; }

        #region Urls
        public static readonly string TokenUrl = "http://m.wufazhuce.com/article";

        /// <summary>
        /// 阅读
        /// {0} id 使用本次最后一个id作为下一次请求的id
        /// {1} token
        /// </summary>
        public readonly string EssayUrl = "http://m.wufazhuce.com/article/ajaxlist/{0}?_token={1}";

        /// <summary>
        /// 音乐
        /// {0} id 使用本次最后一个id作为下一次请求的id
        /// {1} token
        /// </summary>
        public readonly string MusicUrl = "http://m.wufazhuce.com/music/ajaxlist/{0}?_token={1}";

        /// <summary>
        /// 一个
        /// {0} id 使用本次最后一个id作为下一次请求的id
        /// {1} token
        /// </summary>
        public readonly string ContentUrl = "http://m.wufazhuce.com/one/ajaxlist/{0}?_token={1}";

        /// <summary>
        /// 一个
        /// {0} id 使用本次最后一个id作为下一次请求的id
        /// {1} token
        /// </summary>
        public readonly string MovieUrl = "http://m.wufazhuce.com/movie/ajaxlist/{0}?_token={1}";

        #endregion

        public async Task<string> GetTokenAsync()
        {
            string html = await GetAsync(TokenUrl);
            Regex regex = new Regex("One.token = \'(.+)?\'");
            Match match = regex.Match(html);
            if (match.Success)
            {
                return match.Groups[1].Value;
            }
            else
            {
                return string.Empty;
            }
        }

        public async Task<IEnumerable<Answer>> GetAnswersAsync()
        {
            throw new NotImplementedException();
        }

        public async Task<IEnumerable<Content>> GetContentsAsync(int id = 0)
        {
            List<Content> contents = new List<Content>();

            while ( true)
            {
                try
                {
                    var tmp = await GetContentsAsyncInner(id);
                    id = tmp.Last().Id;
                    Debug.WriteLine(id);
                    contents.AddRange(tmp.ToContents());
                }
                catch
                {
                    break;
                }
            }

            return contents;
        }

        public async Task<IEnumerable<Models.ResultModelV2.ContentResult>> GetContentsAsyncInner(int id = 0)
        {
            if (string.IsNullOrEmpty(Token))
            {
                Token = await GetTokenAsync();
            }
        
            string json = await GetJsonAsync(string.Format(ContentUrl, id, Token));
            if (!string.IsNullOrEmpty(json))
            {
                var result = JsonHelper.Deserlialize<ResultTemplate<List<Models.ResultModelV2.ContentResult>>>(json);
                return result.Data;
            }
            else
            {
                return null;
            }
        }

        public async Task<List<Movie>> GetMoviesAsync(int id = 0)
        {
            List<Movie> movies = new List<Movie>();

            while (true)
            {
                try
                {
                    var tmp = await GetMoviesAsyncInner(id);
                    id = tmp.Last().Id;
                    Debug.WriteLine(id);
                    movies.AddRange(tmp.ToMovies());
                }
                catch
                {
                    break;
                }
            }

            return movies;
        }

        public async Task<List<MovieResult>> GetMoviesAsyncInner(int id = 0)
        {
            if (string.IsNullOrEmpty(Token))
            {
                Token = await GetTokenAsync();
            }

            string json = await GetJsonAsync(string.Format(MovieUrl, id, Token));
            if (!string.IsNullOrEmpty(json))
            {
                var result = JsonHelper.Deserlialize<ResultTemplate<List<MovieResult>>>(json);
                return result.Data;
            }
            else
            {
                return null;
            }
        }

        public async  Task<IEnumerable<Serial>> GetSerialsAsync()
        {
            throw new NotImplementedException();
        }

        public async Task<List<Article>> GetArticlesAsync(int id = 0)
        {
            List<Article> articles = new List<Article>();

            while (true)
            {
                try
                {
                    List<Models.ResultModelV2.ArticleResult> articleResults = await GetArticlesAsyncInner(id);
                    id = articleResults.Last().Id;
                    Debug.WriteLine(id); 
                    
                    for (int i = 0; i < articleResults.Count; i++)
                    {
                        ArticleDetailResult articleDetailResult = await GetArticleDetailAsync(articleResults[i].ContentId);
                        LogHelper.WriteLine($"{articleDetailResult.HpMaketime} {articleDetailResult.HpTitle}");
                        Article article = articleDetailResult.ToArticle();
                        article.Author = articleResults[i].Author.ToAuthor();
                        article.ImageUrl = articleResults[i].ImgUrl;
                        articles.Add(article);
                    }
                }
                catch
                {
                    break;
                }
            }
            LogHelper.WriteLine($"Articles' count : {articles.Count}");
            return articles;
        }

        /// <summary>
        /// 获取指定Id的文章内容
        /// </summary>
        /// <param name="date">2016-08-01</param>
        public static async Task<ArticleDetailResult> GetArticleDetailAsync(int contentId)
        {
            string json = await GetJsonAsync(string.Format(ServiceUri.EssayDetail, contentId));
            if (!string.IsNullOrEmpty(json))
            {
                var result = JsonHelper.Deserlialize<ResultTemplate<ArticleDetailResult>>(json);
                return result.Data;
            }
            else
            {
                return null;
            }
        }

        public async Task<List<Models.ResultModelV2.ArticleResult>> GetArticlesAsyncInner(int id = 0)
        {
            if (string.IsNullOrEmpty(Token))
            {
                Token = await GetTokenAsync();
            }

            string json = await GetJsonAsync(string.Format(EssayUrl, id, Token));
            if (!string.IsNullOrEmpty(json))
            {
                var result = JsonHelper.Deserlialize<ResultTemplate<List<Models.ResultModelV2.ArticleResult>>>(json);
                return result.Data;
            }
            else
            {
                return null;
            }
        }

        public async Task<List<Music>> GetMusicsAsync(int id = 0)
        {
            List<Music> musics = new List<Music>();

            while (true)
            {
                try
                {
                    var tmp = await GetMusicsAsyncInner(id);
                    id = tmp.Last().Id;
                    Debug.WriteLine(id);
                    musics.AddRange(tmp.ToMusics());
                }
                catch
                {
                    break;
                }
            }

            return musics;
        }

        public async Task<List<MusicResult>> GetMusicsAsyncInner(int id = 0)
        {
            if (string.IsNullOrEmpty(Token))
            {
                Token = await GetTokenAsync();
            }

            string json = await GetJsonAsync(string.Format(MusicUrl, id, Token));
            if (!string.IsNullOrEmpty(json))
            {
                var result = JsonHelper.Deserlialize<ResultTemplate<List<MusicResult>>>(json);
                return result.Data;
            }
            else
            {
                return null;
            }
        }
    }
}
